﻿<#
.SYNOPSIS 
    Retrieves the PeopleSoft configuration parameters.
.DESCRIPTION 
    Use this command to retrieve the PeopleSoft Application Server configuration parameters for a specific domain.
    This command can be used to revrieve parts or all of the configuration file.
.NOTES 
    File Name  : Get-PsftConfiguration.ps1 
    Author     : Scott Kearney - scott@kearney.tk 
    Requires   : PowerShell V3 
.EXAMPLE 
    Get-PsftConfiguration -PS_HOME C:\psoft\PS_HOME -PS_CFG_HOME C:\psoft\PS_CFG_HOME -ServerType AppServer -Domain DOMAIN1 -Section Startup -Name DBName
    Retrieves the database name for the application server domain named DOMAIN1.
.EXAMPLE 
    Get-PsftConfiguration -PS_HOME C:\psoft\PS_HOME -PS_CFG_HOME C:\psoft\PS_CFG_HOME -ServerType AppServer -Domain DOMAIN1 -Section "JOLT Listener"
    Retrieves all options under the "JOLT Listener" section of the application server configuration for DOMAIN1.
.EXAMPLE 
    Get-PsftConfiguration -PS_HOME C:\psoft\PS_HOME -PS_CFG_HOME C:\psoft\PS_CFG_HOME -ServerType AppServer -Domain DOMAIN1
    Retrieves all sections and options of the application server configuration for DOMAIN1.
.EXAMPLE 
    Get-PsftConfiguration -PS_HOME C:\psoft\PS_HOME -PS_CFG_HOME C:\psoft\PS_CFG_HOME -ServerType AppServer -Domain DOMAIN1 -Name Port
    Retrieves all options with the name "Port" under any section of the application server configuration for DOMAIN1.
.PARAMETER PS_HOME
    The full path to the PS_HOME directory for this domain.
.PARAMETER PS_CFG_HOME
    The full path to the PS_CFG_HOME directory for this domain.
.PARAMETER ServerType
    The type of server on which to perform the action.
.PARAMETER Domain
    The name of the domain on which to perform the action.
.PARAMETER Section
    If specified, limits the scope to only options from this section of the configuration file.
.PARAMETER Name
    If specified, limits the scope to only options with this name in the configuration file.
#> 
function Get-PsftConfiguration
{
    [CmdletBinding(SupportsShouldProcess=$True,ConfirmImpact='Low')]
    [OutputType([Hashtable])]
    Param
    (
        # The full path to the PS_HOME directory for this domain.
        # See http://docs.oracle.com/cd/E41633_01/pt853pbh1/eng/pt/tsvt/concept_UnderstandingPS_HOMEandPS_CFG_HOME-eb7ece.html
        [Parameter(Mandatory=$false,
                   ValueFromPipelineByPropertyName=$true,
                   HelpMessage = "The full path to the PS_HOME directory for this domain.",
                   Position=0)]
        [ValidateScript({Validate_PS_HOME $_})]
        [String]
        $PS_HOME,

        # The full path to the PS_CFG_HOME directory for this domain.
        # See http://docs.oracle.com/cd/E41633_01/pt853pbh1/eng/pt/tsvt/concept_UnderstandingPS_HOMEandPS_CFG_HOME-eb7ece.html
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   HelpMessage = "The full path to the PS_CFG_HOME directory for this domain.",
                   Position=1)]
        [ValidateScript({Validate_PS_CFG_HOME $_})]
        [String]
        $PS_CFG_HOME,

        # The type of server on which to perform the action.
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   HelpMessage = "The type of server on which to perform the action.",
                   Position=2)]
        [ValidateSet("AppServer","PrcsScheduler")]
        $ServerType,

        # The name of the domain on which to perform the action.
        # Should be a directory under the PS_CFG_HOME
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   HelpMessage = "The name of the domain on which to perform the action.",
                   Position=3)]
        [ValidateScript({Validate_Domain $PS_CFG_HOME $ServerType $_})]
        [String]
        $Domain,

        # If specified, limits the scope to only options from this section of the configuration file.
        # Should be a section name from the psappsrv.cfg file.
        # E.g. [JOLT Listener]
        [Parameter(Mandatory=$false,
                   ValueFromPipelineByPropertyName=$true,
                   HelpMessage = "A section name from psappsrv.cfg. E.g. ""Jolt Listener""",
                   Position=4)]
        # TODO: Validate the section name from the file
        [String]
        $Section,

        # If specified, limits the scope to only options with this name in the configuration file.
        # Should be an option name from psappsrv.cfg
        # E.g. Port=9000
        [Parameter(Mandatory=$false,
                   ValueFromPipelineByPropertyName=$true,
                   HelpMessage = "An option name from psappsrv.cfg. E.g. ""Port""",
                   Position=5)]
        [String]
        $Name
    )

    Begin
    {
    }
    Process
    {
        # Set up variables
        $return = $null
        $pscfg = $null

        switch ($ServerType)
        {
            'AppServer' {$pscfgFilePath = "$PS_CFG_HOME\appserv\$Domain\psappsrv.cfg"}
            'PrcsScheduler' {$pscfgFilePath = "$PS_CFG_HOME\appserv\prcs\$Domain\psprcs.cfg"}
        }
        
        Write-Verbose "Reading from $pscfgFilePath"

        # Must use an OrderedDictionary so that the configuration gets written back to the
        # file (psappsrv.cfg) in the correct order.
        # This makes the file human-readable. Otherwise, it's a jumbled mess (although still valid).

        [System.Collections.Specialized.OrderedDictionary]$pscfg = Get-CfgContent $pscfgFilePath

        # Decide what to return based on the supplied parameters.
        # (All code paths return inside their if statement.)
        # (The first match on conditions will be returned.)

        if ($Section -and $Name){
            # If both the Section and the Name are specified
            
            # Returns a hashtable representing the information requested
            $return = $pscfg | Select @{
                Name="$Section";
                Expression={
                    $_.$Section | Select @{
                        Name="$Name";
                        Expression={$_.$Name}
                    }
                }
            }

            # Return an object representing the option for the specified Section and Name
            return $return

        } elseif ($Section){
            # If only the Section is specified, and not the Name

            # Returns a hashtable representing the information requested
            $return = $pscfg | Select @{
                Name="$Section";
                Expression={$_.$Section}
            }

            # Return just the Section with the specified name
            return $return

        } elseif ($Name){
            # If only the Name is specified, and not the Section

            $return = $pscfg | Select @{
                Name="$Name";
                Expression={$_.Values.$Name}
            }

            # Return just the options with the specified name
            return $return

        } else {
            #If neither the Section nor the name are specified

            # Return every configuration option
            return $pscfg
        }

    }
    End
    {
    }
}